package com.navinfo.tripanalysis.offline.service.impl.huashen;

import com.navinfo.tripanalysis.common.pojo.*;
import com.navinfo.tripanalysis.common.util.CommonUtils;
import com.navinfo.tripanalysis.offline.pojo.LoadDataParam;
import com.navinfo.tripanalysis.offline.service.LoadPoint0200Service;
import com.navinfo.tripanalysis.offline.service.impl.AbstractLoadPoint0200Service;
import com.navinfo.tripanalysis.offline.util.PointUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.spark.sql.Row;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * 一汽通过Hive加载0200协议数据
 * @author hmc
 */
@RunningType(value = RunningTypeEnum.HS, interfaceClass = LoadPoint0200Service.class )
public class LoadPoint0200ServiceHiveImpl extends AbstractLoadPoint0200Service {
    /**
     * 覆盖默认的TID字段
     */
    private String TID_NAME = "terminalid";

    public LoadPoint0200ServiceHiveImpl() {
        COL_NAMES.addAll(Arrays.asList(TID_NAME, "gpsdate", "status", "additionalarm","statusaddition",
                "mileage", "ispatch", "speed", "height", "originallat",
                "originallng", "latitude", "longitude","direction", "electricvehicle",
                "standardmileage", "standardfuelcon", "tcuload", "vecuload"));
    }

    @Override
    protected String getWhereSql(LoadDataParam param) {
        List<Long> tidList = param.getTidList();

        //分批处理
        String batchWhere = PointUtils.getBatchWhereSql(param);
        StringBuilder sb = new StringBuilder(StringUtils.isEmpty(batchWhere) ? "" : batchWhere+" and ")
            .append(" gpsdate!=0 and gpsdate is not null and "+ TID_NAME +"!=0 and "+ TID_NAME +" is not null ")
            .append(CollectionUtils.isNotEmpty(tidList) ? String.format(" and %s in(%s) ", TID_NAME, CommonUtils.mkString(tidList, ",")) : "");

        return sb.toString();
    }

    @Override
    protected String getHDFSWhereSql(LoadDataParam param){
        List<Long> tidList = param.getTidList();

        StringBuilder sb = new StringBuilder(" gpsdate!=0 and gpsdate is not null and "+ TID_NAME +"!=0 and "+ TID_NAME +" is not null ")
                .append(CollectionUtils.isNotEmpty(tidList) ? String.format(" and %s in(%s) ", TID_NAME, CommonUtils.mkString(tidList, ",")) : "");

        return sb.toString();
    }

    @Override
    protected Point getPoint(Row row) {
        Point0200 point = new Point0200();
        point.setTid(row.getAs(TID_NAME));
        point.setProtocol(ProtocolEnum.LOCATION);
        point.setGpsTime((Long.parseLong(Optional.ofNullable(row.getAs("gpsdate")).orElse("0").toString())) * 1000L);
        point.setHeight(Double.parseDouble(Optional.ofNullable(row.getAs("height")).orElse("0").toString()));
        point.setOriginalLat(Integer.parseInt(Optional.ofNullable(row.getAs("originallat")).orElse("0").toString()));
        point.setOriginalLng(Integer.parseInt(Optional.ofNullable(row.getAs("originallng")).orElse("0").toString()));
        point.setLatitude(Integer.parseInt(Optional.ofNullable(row.getAs("latitude")).orElse("0").toString()));
        point.setLongitude(Integer.parseInt(Optional.ofNullable(row.getAs("longitude")).orElse("0").toString()));
        point.setDirection(Integer.parseInt(row.getAs("direction").toString()));
        //标准速度，标准速度为0取gps速度
        double speed = Double.parseDouble(Optional.ofNullable(row.getAs("electricvehicle")).orElse("0").toString()) / 100.0;
        point.setSpeedKmh(speed==0 ? Double.parseDouble(Optional.ofNullable(row.getAs("speed")).orElse("0").toString())/100.0 : speed);
        //0200特有，GPS里程
        point.setGpsMileage( BigDecimal.valueOf(Long.parseLong(String.valueOf(Optional.ofNullable(row.getAs("mileage")).orElse("0")))).divide(
                new BigDecimal("1000"), 3, BigDecimal.ROUND_DOWN).doubleValue());

        //0200特有，标准总里程，总油耗
        point.setStandardMileage(Float.parseFloat(Optional.ofNullable(row.getAs("standardmileage")).orElse("0").toString()));
        point.setStandardFuelCons(Float.parseFloat(Optional.ofNullable(row.getAs("standardfuelcon")).orElse("0").toString()));

        //0200特有，是否补传，acc状态
        point.setPatch(Boolean.parseBoolean(Optional.ofNullable(row.getAs("ispatch")).orElse("false").toString()) ? 1 : 0);
        point.setAccStatus(com.navinfo.tripanalysis.common.util.PointUtils.parseStatus(Long.parseLong(String.valueOf(Optional.ofNullable(row.getAs("status")).orElse("0"))), 0));

        //车辆状态附加信息
        PointUtils.setStatusAddition4YQ(point, row.getAs("statusaddition"));

        //附加报警位
        PointUtils.setAdditionAlarm(point,  row.getAs("additionalarm"));

        //0200特有，序列号
        if (isSupportSerialNumber()) {
            Integer number = row.getAs(SERIALNUMBER_NAME);
            if (number != null) {
                point.setSerialNumber(number);
            }
        }

        //0200特有,AMT、VECU载重
        //point.setAmtLoad(Integer.valueOf(row.getAs("tcuload").toString())/100);
        //point.setVecuLoad(Integer.valueOf(row.getAs("vecuload").toString()));

        return point;
    }
}
